#include "includes.h"
#include "structs.h"

idx_t options [METIS_NOPTIONS];
idx_t example_xadj[] = { 0, 2, 5, 8, 11, 13, 16, 20, 24, 28, 31, 33, 36, 39, 42, 44 };
idx_t example_adjncy[] = { 1, 5, 0, 2, 6, 1, 3, 7, 2, 4, 8, 3, 9, 0, 6, 10, 1, 5, 7, 11, 2, 6, 8, 12, 3, 7, 9, 13, 4, 8, 14, 5, 11, 6, 10, 12, 7, 11, 13, 8, 12, 14, 9, 13 };
idx_t example_nvtxs = sizeof(example_xadj)/sizeof(example_xadj[0])-1;
idx_t ncon = 1;
idx_t vsize;
idx_t *adjwgt;
idx_t npart = 4;
idx_t tpwgt;
idx_t ubvec ;
idx_t *vwgt;
idx_t *part;
idx_t edgecut;
FILE *vfile, *efile, *rfile;
char *program_name;
idx_t *xadj, *adjncy, *adjwgt;

void simple_parse_arg(int argc, char **argv)
{
        program_name = argv[0];
        if(argc != 4) 
                errexit("Usage: %s vfile efile npart\n", program_name);
        vfile = fopen(argv[1], "r");
        efile = fopen(argv[2], "r"); 
        if(vfile && efile) {
                npart = atoi(argv[3]);
                if(npart <= 1)
                        errexit("%s: npart should > 1\n", program_name);
        }
        else
                errexit("%s: open filed error\n", program_name);
}

/* DONOT USE THIS 
 * NO ZLOG SUPPORT
 * SLOW(O(vn * en)
 */

int driver(FILE *vfile, FILE *efile, FILE *rfile)
{   
        igraph_vector_ptr_t vertices, edges;
        igraph_vector_int_t ixadj, iadjncy, ivwgt, iadjwgt;

        int en = efile2edges(efile, &edges);
        int vn = vfile2vertices(vfile, ncon, &vertices);

        vector2adjlistEX(&vertices, &edges, &ixadj, &iadjncy, &ivwgt, &iadjwgt, ncon);
        
        idx_t *part = calloc(sizeof(idx_t), vn);
        idx_t edgecut;
        xadj = ixadj.stor_begin;
        adjncy = iadjncy.stor_begin;
        vwgt = ivwgt.stor_begin;
        adjwgt = iadjwgt.stor_begin;

        /* METIS_PartGraphKway */
        METIS_PartGraphKway(&vn, &ncon, xadj, adjncy, 0    , 0, adjwgt, &npart, 0,0,0, &edgecut, part);
        print_partition(rfile, part, vn);
       
#ifndef NDEBUG
        printf("edgecut -> %d\n", edgecut); 
#endif
        fclose(rfile);
        fclose(vfile);
        fclose(efile);
        
        free(part);
        return 0;
}


int driver0(FILE *vfile, FILE *efile, FILE *rfile)
{   
        zlog_category_t *mylog = zlog_get_category("mylog");
        igraph_vector_ptr_t vertices, edges;
        my_adjlist_t myadjlist;
        igraph_vector_int_t ixadj, iadjncy, ivwgt, iadjwgt;
        int ncon=2;

        zlog_info(mylog, "efile2edges begin");
        int en = efile2edges(efile, &edges);
        zlog_info(mylog, "efile2edges finish");

        zlog_info(mylog, "vfile2vertices begin");
        int vn = vfile2vertices(vfile, ncon, &vertices);
        zlog_info(mylog, "vfile2vertices finish");

        zlog_info(mylog, "vector2my_adjlist begin");
        vector2my_adjlist(&vertices, &edges, &myadjlist);
        zlog_info(mylog, "vector2my_adjlist finish");

        zlog_info(mylog, "my_adjlist2adjlist begin");
        my_adjlist2adjlist(&vertices, &myadjlist, &ixadj, &iadjncy, &ivwgt, &iadjwgt);
        zlog_info(mylog, "my_adjlist2adjlist finish");

        /* prepare for partition input */
        part = calloc(sizeof(idx_t), vn);
        idx_t edgecut;
        xadj = ixadj.stor_begin;
        adjncy = iadjncy.stor_begin;
        vwgt = ivwgt.stor_begin;
        adjwgt = iadjwgt.stor_begin;

        zlog_info(mylog, "METIS_PartGraphKway begin");
        /* METIS_PartGraphKway */
        METIS_PartGraphKway(&vn, &ncon, xadj, adjncy, vwgt, 0, adjwgt, &npart, 0,0,0, &edgecut, part);
        zlog_info(mylog, "METIS_PartGraphKway finish");

        /* to stdout */
        print_partition(rfile, part, vn);

        zlog_info(mylog, "partition done, edgecut=%d", edgecut);
        fclose(rfile);
        fclose(vfile);
        fclose(efile);
        
        return 0;
}



/* void clean_up() */
/* { */
/*         for */
int main(int argc , char ** argv) 
{
        int err = zlog_init(ZLOG_CONF_PATH);
        if(err)
                errexit("zlog_init failed %s\n", ZLOG_CONF_PATH);
        zlog_category_t *mylog = zlog_get_category("mylog");
        if(NULL == mylog)
                errexit("zlog_get_category failed\n");
        simple_parse_arg(argc, argv);
        rfile = stdout;
        driver0(vfile, efile, rfile);
        return 0;
}        

